<?php

declare(strict_types=1);

namespace EthanZ\HyperfExt\Model;

use Hyperf\Database\Model\Concerns\CamelCase;
use Hyperf\Database\Schema\Schema;
use Hyperf\DbConnection\Db;
use Hyperf\DbConnection\Model\Model as BaseModel;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\ModelCache\Cacheable;
use Hyperf\ModelCache\CacheableInterface;
use Hyperf\Database\Model\Builder;
use Hyperf\Redis\Redis;
use Hyperf\Snowflake\IdGeneratorInterface;

abstract class Model extends BaseModel implements CacheableInterface
{

    use Cacheable, CamelCase;


    protected     $dateFormat           = 'U';

    public string $subTableSuffixFormat = 'Y';

    public string $suffix;

    public string $initialTable;


    /**
     * 设置表后缀
     *
     * @param $suffix
     *
     * @return Builder
     */
    public static function setSuffix($suffix): Builder
    {
        $instance = new static;

        if ($suffix) {
            $instance->suffix       = (string)$suffix;
            $instance->initialTable = $instance->getTable();
            $instance->table        = $instance->getTable() . '_' . $suffix;
        }

        $instance->createSubTable();

        return $instance->newQuery();
    }


    /**
     * 根据sfId设置表后缀
     *
     * @param int $sfId
     *
     * @return Builder
     */
    public static function getModelBySnack(int $sfId): Builder
    {
        $instance = new static;

        $time   = make(IdGeneratorInterface::class)->degenerate($sfId)->getTimestamp() / 1000;
        $suffix = date($instance->subTableSuffixFormat, (int)$time);

        return self::setSuffix($suffix);
    }

    /**
     * 创建子表
     */
    public function createSubTable(): void
    {
        $tableName = $this->getTable();
        $redisKey  = env('APP_ID') . ':createSubTable:' . $tableName;
        $redis     = make(Redis::class);
        if (!$redis->exists($redisKey)) {
            // 缓存判断不存在分表
            if (!Schema::hasTable($tableName)) {
                $lastTableName = $this->initialTable . '_' . (int)($this->suffix - 1);
                if (!Schema::hasTable($lastTableName)) {
                    // 是否存在上一个分表 存在获取上一个分表创建新的分表
                    $lastTableName = $this->initialTable;
                }
                Db::select("CREATE TABLE `{$tableName}` LIKE `{$lastTableName}`;");
            }

            $redis->set($redisKey, '1');
        }
    }


    /**
     * 自定义分页
     *
     * @param Builder $query
     *
     * @return array
     */
    public function scopePage(Builder $query): array
    {
        $requestInterface = make(RequestInterface::class);

        $page     = $requestInterface->input('page', 1);
        $pageSize = $requestInterface->input('pageSize', 15);
        $total    = $query->count();

        if ($total) {
            $list = $query
                ->forPage($page, $pageSize)
                ->get();
        }

        return [
            'data'  => $list ?? [],
            'total' => $total,
        ];
    }
}
